﻿using MailKit.Net.Smtp;
using MailKit.Security;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Zhp.Common.Helper;
using Zhp.Entity.Message.Email;
using Zhp.IService.Message.Email;

namespace Zhp.Service.Message.Email
{
    public class SmtpBuilder : ISmtpBuilder
    {
        private readonly IEmailAccountService _emailAccountService;

        public SmtpBuilder(IEmailAccountService emailAccountService)
        {
            _emailAccountService = emailAccountService;
        }

        public async Task<SmtpClient> BuildAsync(EmailAccount emailAccount)
        {
            if (emailAccount is null)
            {
                throw new Exception("Email account could not be loaded");
            }

            var client = new SmtpClient
            {
                ServerCertificateValidationCallback = ValidateServerCertificate
            };

            try
            {
                await client.ConnectAsync(
                    emailAccount.Host,
                    emailAccount.Port,
                    emailAccount.EnableSsl
                        ? SecureSocketOptions.SslOnConnect
                        : SecureSocketOptions.StartTlsWhenAvailable);

                if (emailAccount.UseDefaultCredentials)
                {
                    await client.AuthenticateAsync(CredentialCache.DefaultNetworkCredentials);
                }
                else if (!string.IsNullOrWhiteSpace(emailAccount.Username))
                {
                    await client.AuthenticateAsync(new NetworkCredential(emailAccount.Username, emailAccount.Password.ToDecryptRSAString()));
                }

                return client;
            }
            catch (Exception ex)
            {
                client.Dispose();
                throw new Exception(ex.Message, ex);
            }
        }

        public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}
